package com.boguan.web.controller.pulsar;

import org.apache.pulsar.client.api.Authentication;
import org.apache.pulsar.client.api.AuthenticationDataProvider;
import org.apache.pulsar.client.api.PulsarClientException;
import org.apache.pulsar.shade.com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.pulsar.shade.com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.pulsar.shade.org.apache.commons.codec.binary.Hex;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.UUID;

public class WeiYuAuthentication implements Authentication {

    private final String commandData;

    public WeiYuAuthentication(String appId, String appSecret) throws NoSuchAlgorithmException, InvalidKeyException {
        String noncestr = UUID.randomUUID().toString();
        ObjectMapper mapper = new ObjectMapper();
        ObjectNode rootNode = mapper.createObjectNode();
        rootNode.put("appId", appId);
        rootNode.put("noncestr", noncestr);
        rootNode.put("sign", getSign(appId + noncestr, appSecret));

        commandData = rootNode.toString();
    }

    private String getSign(String data, String secret) throws NoSuchAlgorithmException, InvalidKeyException {
        Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
        sha256_HMAC.init(secretKey);
        byte[] hash = sha256_HMAC.doFinal(data.getBytes());

        return Hex.encodeHexString(hash);
    }

    @Override
    public String getAuthMethodName() {
        return "etor";
    }

    @Override
    public AuthenticationDataProvider getAuthData() throws PulsarClientException {
        return new AuthenticationDataProvider() {
            @Override
            public boolean hasDataForHttp() {
                return false;
            }

            @Override
            public boolean hasDataFromCommand() {
                return true;
            }

            @Override
            public String getCommandData() {
                return commandData;
            }
        };
    }

    @Override
    public void configure(Map<String, String> authParams) {

    }

    @Override
    public void start() throws PulsarClientException {

    }

    @Override
    public void close() throws IOException {

    }
}
